package com.czk.bootlettuce.controller;

import com.czk.bootlettuce.consitant.FormNoTypeEnum;
import com.czk.bootlettuce.utils.FormNoSerialUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/11/4 21:46
 */
@Component
public class FormNoGenerateComponent {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    public String generateFormNo(FormNoTypeEnum formNoTypeEnum) {
        // 拿到前缀
        String formNoPrefix = FormNoSerialUtil.getFormNoPrefix(formNoTypeEnum);
        // 拿到缓存key
        String cacheKey = FormNoSerialUtil.getCacheKey(formNoPrefix);
        // 获取长度
        Long incrementalSerial = getIncr(cacheKey, getCurrent2TodayEndMillisTime());
        // 组合单号并补全流水号
        return FormNoSerialUtil
                .completionSerial(formNoPrefix, incrementalSerial, formNoTypeEnum);
    }

    private Long getIncr(String key, Long liveTime) {
        RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, Objects.requireNonNull(redisTemplate.getConnectionFactory()));
        long increment = redisAtomicLong.getAndIncrement();
        if (increment == 0 && liveTime > 0) {
            redisAtomicLong.expire(liveTime, TimeUnit.MILLISECONDS);
        }
        return increment;
    }

    /**
     * @return 现在到今天结束的毫秒数
     */
    private Long getCurrent2TodayEndMillisTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);

        return todayEnd.getTimeInMillis() - System.currentTimeMillis();
    }
}
